package com.kokotchy.tuxcontrol;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Iterator;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.app.ListActivity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.AdapterView.AdapterContextMenuInfo;

import com.kokotchy.tuxcontrol.components.EditTextDialog;

/**
 * Attitunes activity
 * 
 * $Date: 2009-12-30 15:09:35 +0000 (Wed, 30 Dec 2009) $
 * 
 * @author $Author: kokotchy $
 * @version $Revision: 18 $
 * 
 */
public class Attitunes extends ListActivity {

	/**
	 * Adapter for displaying an attitune
	 * 
	 * $Date: 2009-12-30 15:09:35 +0000 (Wed, 30 Dec 2009) $
	 * 
	 * @author $Author: kokotchy $
	 * @version $Revision: 18 $
	 */
	private class AttituneAdapter extends BaseAdapter {

		/**
		 * Class for caching information
		 * 
		 * @author $Author: kokotchy $
		 * @version $Revision: 18 $
		 * 
		 */
		class ViewHolder {
			/**
			 * Author of the attitune
			 */
			TextView author;

			/**
			 * Description of the attitune
			 */
			TextView description;

			/**
			 * Icon of the attitune
			 */
			ImageView icon;

			/**
			 * Name of the attitune
			 */
			TextView name;
		}

		/**
		 * Context
		 */
		private Context mContext;

		/**
		 * Images for the category of the attitune
		 */
		private HashMap<String, Bitmap> mImages;

		/**
		 * Inflater used to display an attitune
		 */
		private LayoutInflater mInflater;

		/**
		 * Create a new AttituneAdapter
		 * 
		 * @param context
		 *            Context
		 */
		public AttituneAdapter(Context context) {
			mContext = context;
			mInflater = LayoutInflater.from(context);
			mImages = new HashMap<String, Bitmap>();

			loadImages("alert", R.drawable.att_icon_alert);
			loadImages("education", R.drawable.att_icon_education);
			loadImages("fun", R.drawable.att_icon_fun);
			loadImages("kids", R.drawable.att_icon_kids);
			loadImages("messages", R.drawable.att_icon_messages);
			loadImages("music", R.drawable.att_icon_music);
			loadImages("others", R.drawable.att_icon_others);
			loadImages("system", R.drawable.att_icon_system);
		}

		@Override
		public int getCount() {
			return attitunes.size();
		}

		@Override
		public Object getItem(int position) {
			Iterator<String> iterator = attitunes.keySet().iterator();
			int i = 0;
			while (iterator.hasNext()) {
				if (position == i) {
					return attitunes.get(iterator.next());
				}
				iterator.next();
				i++;
			}
			return null;
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			ViewHolder holder;
			if (convertView == null) {
				convertView = mInflater.inflate(R.layout.attitune_row, null);

				holder = new ViewHolder();
				holder.icon = (ImageView) convertView
						.findViewById(R.id.AttIcon);
				holder.name = (TextView) convertView.findViewById(R.id.AttName);
				holder.description = (TextView) convertView
						.findViewById(R.id.AttDescription);
				holder.author = (TextView) convertView
						.findViewById(R.id.AttAuthor);

				convertView.setTag(holder);
			} else {
				holder = (ViewHolder) convertView.getTag();
			}

			Attitune attitune = (Attitune) getItem(position);
			holder.name.setText(attitune.getName());
			holder.description.setText(attitune.getDescription());
			holder.icon.setImageBitmap(mImages.get(attitune.getCategory()
					.toLowerCase()));
			holder.author.setText(attitune.getAuthor());

			return convertView;
		}

		/**
		 * Load the given image
		 * 
		 * @param name
		 *            Name of the image
		 * @param id
		 *            Id of the resource
		 */
		private void loadImages(String name, int id) {
			Bitmap image = BitmapFactory.decodeResource(
					mContext.getResources(), id);
			mImages.put(name, image);
		}
	}

	/**
	 * Id of the item in the contextual menu
	 */
	private static final int PLAY_ATTITUNE = Menu.FIRST;

	/**
	 * TAG used when debugging
	 */
	private static final String TAG = "TuxAttitunes";

	/**
	 * TODO Fill it
	 */
	private static final int EDITTEXT_DIALOG = 1;

	/**
	 * TODO Fill it
	 */
	private static final String DEFAULT_IP = "192.168.1.21";

	/**
	 * TODO Fill it
	 */
	private static final int DEFAULT_PORT = 54321;

	/**
	 * Attitune Adapter
	 */
	private AttituneAdapter attituneAdapter;

	/**
	 * List of attitunes
	 */
	protected HashMap<String, Attitune> attitunes;

	/**
	 * TODO Fill it
	 */
	private String mHost;

	/**
	 * TODO Fill it
	 */
	private int mPort;

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case PLAY_ATTITUNE:
			AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
					.getMenuInfo();
			Log.i(TAG, "ID of the attitune: " + info.id);
			Attitune attitune = (Attitune) attituneAdapter
					.getItem(info.position);
			Log.i(TAG, "Name of the attitune: " + attitune.getName());
			Bundle bundle = new Bundle();
			bundle.putString("attituneName", attitune.getName());
			bundle.putInt("type", Attitune.ATTITUNE_FILE);
			Intent intent = new Intent();
			intent.putExtras(bundle);
			setResult(RESULT_OK, intent);
			finish();
			return true;
		}
		return super.onContextItemSelected(item);
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		menu.add(0, PLAY_ATTITUNE, 0, R.string.menu_play_attitune);
	}

	/**
	 * Load the attitunes from the server
	 * 
	 * @return List of attitunes
	 */
	private HashMap<String, Attitune> loadAttitunes() {
		HashMap<String, Attitune> result = new HashMap<String, Attitune>();

		try {
			String urlFormat = "http://%s:%d/0/attitune_manager/attitunes_infos?empty";
			URL list = new URL(String.format(urlFormat, mHost, mPort));
			URLConnection connection = list.openConnection();

			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(new InputSource(connection
					.getInputStream()));
			Node root = document.getFirstChild();
			int length = root.getChildNodes().getLength();
			for (int i = 0; i < length; i++) {
				Node data = root.getChildNodes().item(i);
				int length2 = data.getChildNodes().getLength();
				Attitune attitune = new Attitune();
				for (int j = 0; j < length2; j++) {
					Node element = data.getChildNodes().item(j);
					if (element.getChildNodes().getLength() == 1) {
						String nodeName = element.getNodeName();
						String nodeValue = element.getFirstChild()
								.getNodeValue();
						attitune.setField(nodeName, nodeValue);
					}
				}
				if (attitune.getName() != null) {
					result.put(attitune.getName(), attitune);
				}
			}
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		}

		return result;
	}

	/**
	 * Update host and port value from preferences
	 */
	private void updateServerInformation() {
		SharedPreferences preferences = PreferenceManager
				.getDefaultSharedPreferences(this);
		mHost = preferences.getString("ip_server_preference", DEFAULT_IP);
		mPort = preferences.getInt("port_server", DEFAULT_PORT);
		String format = "updateServerInformation! Connection to %s:%d";
		Log.v(TAG, String.format(format, mHost, mPort));
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case EDITTEXT_DIALOG:
			switch (resultCode) {
			case RESULT_OK:
				Intent intent = new Intent();
				Bundle bundle = new Bundle();
				bundle.putString("url", data.getStringExtra("content"));
				bundle.putInt("type", Attitune.ATTITUNE_URL);
				intent.putExtras(bundle);
				setResult(resultCode, intent);
				break;
			case RESULT_CANCELED:
				setResult(resultCode);
				break;
			}
			finish();
			break;
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.attitune_list);
		updateServerInformation();

		attitunes = loadAttitunes();

		attituneAdapter = new AttituneAdapter(this);
		setListAdapter(attituneAdapter);
		registerForContextMenu(getListView());

		Button addByURL = (Button) findViewById(R.id.bLoadUrl);
		addByURL.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				startActivityForResult(new Intent(getApplicationContext(),
						EditTextDialog.class), EDITTEXT_DIALOG);
			}
		});
	}

}
